package pr.platerecognization;

import android.Manifest;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.util.Log;

import androidx.core.app.ActivityCompat;

import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import pr.platerecognization.constans.Constant;

public class OcrBusiness {

    private static OcrBusiness instance;
    private Application mContext;
    public static long handle;
    public synchronized static OcrBusiness getInstance(Context context){
        if(instance==null){
            instance = new OcrBusiness(context);
        }
        return instance;
    }

    public OcrBusiness(Context context) {
        this.mContext = (Application) context.getApplicationContext();
        if(OpenCVLoader.initDebug()){
            Log.d("Opencv","opencv load_success");
        }else{
            Log.d("Opencv","opencv can't load opencv .");
        }
    }




    public void initRecognizer() throws Exception {
        Log.d("Opencv","initRecognizer = ");
        if(ActivityCompat.checkSelfPermission(mContext,Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED){
            throw new Exception("android.permission.WRITE_EXTERNAL_STORAGE isn't open");
        }
        copyFilesFromAssets(mContext, Constant.ASSET_PATH, Constant.SDCARD_PATH);

        handle  =  PlateRecognition.InitPlateRecognizer(
                Constant.CASCADE_FILENAME,
                Constant.FINEMAPPING_PROTOTXT,Constant.FINEMAPPING_CAFFEMODEL,
                Constant.SEGMENTATION_PROTOTXT,Constant.SEGMENTATION_CAFFEMODEL,
                Constant.CHARACTER_PROTOTXT,Constant.CHARACTER_CAFFEMODEL,
                Constant.SEGMENTATIONFREE_PROTOTXT,Constant.SEGMENTATIONFREE_CAFFEMODEL );
        Log.d("Opencv","handle = "+handle);
    }

    public PlateInfo SimpleRecog(Bitmap bmp, int dp){
        float dp_asp  = dp/10.f;
        Mat mat_src = new Mat(bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC4);
        float new_w = bmp.getWidth()*dp_asp;
        float new_h = bmp.getHeight()*dp_asp;
        Size sz = new Size(new_w,new_h);
        Utils.bitmapToMat(bmp, mat_src);
        Imgproc.resize(mat_src,mat_src,sz);
        return  PlateRecognition.PlateInfoRecognization(mat_src.getNativeObjAddr(),handle);
    }


    public void copyFilesFromAssets(Context context, String oldPath, String newPath) {
        try {
            String[] fileNames = context.getAssets().list(oldPath);
            if (fileNames.length > 0) {
                // directory
                File file = new File(newPath);
                if (!file.mkdir())
                {
                    Log.d("mkdir","can't make folder");

                }
//                    return false;                // copy recursively
                for (String fileName : fileNames) {
                    copyFilesFromAssets(context, oldPath + "/" + fileName,
                            newPath + "/" + fileName);
                }
            } else {
                // file
                InputStream is = context.getAssets().open(oldPath);
                FileOutputStream fos = new FileOutputStream(new File(newPath));
                byte[] buffer = new byte[1024];
                int byteCount;
                while ((byteCount = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, byteCount);
                }
                fos.flush();
                is.close();
                fos.close();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public  Bitmap decodeImage(String path) {
        Bitmap res;
        try {
            ExifInterface exif = new ExifInterface(path);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

            BitmapFactory.Options op = new BitmapFactory.Options();
            op.inSampleSize = 1;
            op.inJustDecodeBounds = false;
            //op.inMutable = true;
            res = BitmapFactory.decodeFile(path, op);
            //rotate and scale.
            Matrix matrix = new Matrix();

            if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
                matrix.postRotate(90);
            } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
                matrix.postRotate(180);
            } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
                matrix.postRotate(270);
            }

            Bitmap temp = Bitmap.createBitmap(res, 0, 0, res.getWidth(), res.getHeight(), matrix, true);
            Log.d("com.arcsoft", "check target Image:" + temp.getWidth() + "X" + temp.getHeight());

            if (!temp.equals(res)) {
                res.recycle();
            }
            return temp;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
